﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;

namespace Evan.Plugins
{
    /// <summary>
    /// 上传插件公用类 此处仅支持二进制文件处理  FormData上传上来的二进制文件
    /// 此插件仅处理上传操作 , 同时检测上传的文件是否安全
    /// 特征库在 AppData/trojanlib 
    /// </summary>
    public static class Upload
    {

        private static string fileFolder = Evan.Common.CommFun.GetAppSetting("UploadFolder"); //上传目录名
        private readonly static string fileType = Evan.Common.CommFun.GetAppSetting("UploadType"); //文件类型
        private readonly static long fileSize = int.Parse(Evan.Common.CommFun.GetAppSetting("UploadSize")) * 1024 * 1024; //文件大小0为不限制

        /// <summary>
        /// 上传入口
        /// 可在请求头中包含 header信息 <para>SafeCode 安全码</para> <para>ChildFolder 子文件夹</para> 默认为空
        /// </summary>
        /// <param name="context">用户请求</param>
        /// <param name="uploadKind">用户上传文件种类 image/video/file </param>
        /// <param name="uploadFolder">上传的文件夹 , 相对站点根路径 支持写法 /uploads/ , uploads [不支持只写一个/ ] </param>
        /// <param name="uploadType">上传文件支持的类型 支持写法 BMP|JPEG|JPG|GIF|PNG|TIFF|TXT|DOC|DOCX|RAR|ZIP|XLS|XLSX|PDF|MP4|MP3|IPK|APK</param>
        /// <param name="uploadSize">上传的文件大小 , 单位 MB  默认500</param>
        /// <returns></returns>
        //区分一下上传单文件和上传多文件
        public static fileItemModel UploadProcess(HttpContext context, string uploadKind = "", string uploadFolder = "uploads", string uploadType = "*", int uploadSize = 500)
        {

            //string safecode = context.Request.Headers["SafeCode"];


            int isFormData = 1;
            //int.TryParse(context.Request.Headers["isFormData"], out isFormData);
            if (uploadKind.ToLower() == "image")
            {
                //如果是图片的话可以生成缩略图
            }
            if (uploadKind.ToLower() == "video")
            {

            }
            if (uploadKind.ToLower() == "file")
            {

            }
            //if (string.IsNullOrEmpty(uploadKind))
            //{
            //    //如果为空 , 则默认按照所有的处理
            //}

            if (string.IsNullOrEmpty(uploadType) || uploadType == "*")
            {
                uploadType = fileType;
            }

            string folder = context.Request.Headers["Folder"];
            if (!string.IsNullOrEmpty(folder))
            {
                uploadFolder = uploadFolder.Trim('/');
                uploadFolder = "/" + uploadFolder + "/" + folder + "/";
            }
            else
            {
                uploadFolder = uploadFolder.Trim('/');
                uploadFolder = "/" + uploadFolder + "/";
            }
            //检查文件夹在不在 , 如果文件夹不在的话 , 则
            if (!System.IO.Directory.Exists(System.Web.HttpContext.Current.Server.MapPath(uploadFolder)))
            {
                System.IO.Directory.CreateDirectory(System.Web.HttpContext.Current.Server.MapPath(uploadFolder));
            }

            fileItemModel fileitemmodel = new fileItemModel();

            if (isFormData == 0)
            {
                fileitemmodel.state = "error";
                fileitemmodel.error = "请使用支持FormData的浏览器进行操作 , 比如 Chrome、360浏览器（急速模式）、Firefox";
            }
            else
            {
                //这边是FormData对象上传过来的处理
                HttpFileCollection files = context.Request.Files;
                foreach (string str in files)
                {
                    try
                    {
                        if (IsAllowExtName(files.Get(str).FileName, uploadType)) //&& IsWebImage(files.Get(str).ContentType)
                        {

                            HttpPostedFile FileSave = files[str];  //用key获取单个文件对象HttpPostedFile
                            #region 文件头信息获取检查
                            byte[] FileByte = new byte[2];
                            FileSave.InputStream.Read(FileByte, 0, 2);
                            string ByteStr = string.Concat(FileByte.Select(res => string.Format("{0:X2} ", res))).Replace(" ", "");
                            string FileCheckerRes = Security.FileCheck.FileChecker(ByteStr);
                            #endregion
                            if (string.IsNullOrEmpty(FileCheckerRes))
                            {
                                //检查信息返回为空的话 , 说明是正常情况
                                string FileName = DateTime.Now.ToString("yyyyMMddhhmmss_ffffff");
                                string _FileExt = files.Get(str).FileName;
                                _FileExt = _FileExt.Substring(_FileExt.LastIndexOf('.'), _FileExt.Length - _FileExt.LastIndexOf('.'));
                                string FilePath = uploadFolder + FileName + _FileExt;// +"_" + files.Get(str).FileName;
                                FilePath = FilePath.Replace(" ", "_");
                                string AbsolutePath = context.Server.MapPath(FilePath);
                                FileSave.SaveAs(AbsolutePath);//将上传的东西保存
                                fileitemmodel.state = "success";
                                fileitemmodel.url = FilePath;
                                fileitemmodel.original = files.Get(str).FileName;
                                fileitemmodel.title = FilePath;
                            }
                            else
                            {
                                fileitemmodel.state = "error";
                                fileitemmodel.error = FileCheckerRes;
                            }
                        }
                        else
                        {
                            fileitemmodel.state = "error";
                            fileitemmodel.error = "不允许上传的文件类型";
                        }
                    }
                    catch (Exception ex)
                    {
                        //return_str = "ERROR=上传出错";
                        fileitemmodel.state = "error";
                        fileitemmodel.error = ex.Message;
                    }
                }
            }

            return fileitemmodel;
        }



        /// <summary>
        /// 检测用户上传的文件是否被允许上传
        /// </summary>
        /// <param name="filename"></param>
        /// <param name="uploadType"></param>
        /// <returns></returns>
        public static bool IsAllowExtName(string filename, string uploadType)
        {
            //if (string.IsNullOrEmpty(uploadType) || uploadType == "*")
            //{
            //    return true;
            //}
            string ext = filename.Substring(filename.LastIndexOf('.') + 1, filename.Length - filename.LastIndexOf('.') - 1);
            string[] exts = uploadType.Split('|');
            return exts.Contains(ext.ToUpper());
        }


        #region 将上传model转为返回结果model 并JSON
        /// <summary>
        /// 将上传model转为返回结果model 并JSON
        /// </summary>
        /// <param name="fileItemModel"></param>
        /// <returns></returns>
        public static string ConvertUploadResult(Plugins.Upload.fileItemModel fileItemModel)
        {
            if (fileItemModel != null)
            {
                Model.SysModel.UploadResult uploadResult = new Model.SysModel.UploadResult();
                uploadResult.link = fileItemModel.url;
                uploadResult.msg = fileItemModel.error;
                uploadResult.state = fileItemModel.state;
                string Json = Newtonsoft.Json.JsonConvert.SerializeObject(uploadResult);
                return Json;
            }
            return "";
        }
        #endregion


        #region 判断文件类型是否为WEB格式图片

        /// <summary>
        /// 判断文件类型是否为WEB格式图片
        /// (注：JPG,GIF,BMP,PNG)
        /// </summary>
        /// <param name="contentType">HttpPostedFile.ContentType</param>
        /// <returns>是否为WEB格式图片</returns>
        public static bool IsWebImage(string contentType)
        {
            if ((contentType == "image/pjpeg") || (contentType == "image/jpeg") || (contentType == "image/gif") || (contentType == "image/bmp") || (contentType == "image/png"))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        #endregion

        

        #region   上传组件实体   2019年8月19日15:36:53
        /// <summary>
        /// 张澎 2019年8月19日15:36:59
        /// 上传文件返回的实体
        /// </summary>
        public class fileItemModel
        {
            /// <summary>
            /// 新文件名
            /// </summary>
            public string title { get; set; } = "";
            /// <summary>
            /// 源文件名
            /// </summary>
            public string original { get; set; } = "";
            /// <summary>
            /// 错误信息
            /// </summary>
            public string error { get; set; } = "";
            /// <summary>
            /// 文件是否上传成功
            /// </summary>
            public string state { get; set; } = "";
            /// <summary>
            /// 路径
            /// </summary>
            public string url { get; set; } = "";
        }

        #endregion

    }
}
